package com.ybzl.system.controller.common;

import com.ybzl.common.core.domain.Result;
import com.ybzl.common.utils.DateUtils;
import com.ybzl.common.utils.file.FileUtils;
import io.minio.MinioClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;

import static com.ybzl.common.core.domain.Result.error;
import static com.ybzl.common.core.domain.Result.success;

/**
 * @Author hq
 * @Date 2020/12/25
 * @Description: Minio文件服务
 */
@Api(tags = "minio文件服务")
@Slf4j
@RestController
@RequestMapping("/minio")
public class MinioController {


    @Value("${minio.url}")
    private String url;
    @Value("${minio.accessKey}")
    private String accessKey;
    @Value("${minio.secretKey}")
    private String secretKey;
    @Value("${minio.bucketName}")
    private String bucketName;

    /**
     * 上传文件到minio服务
     *
     * @param file
     * @return
     */
    @ApiOperation("文件上传")
    @PostMapping(value = "/upload")
    public Result upload(@RequestParam(required = false) String folderName, @RequestPart("file") MultipartFile file) {
        try (InputStream is = file.getInputStream()) {
            MinioClient minioClient = new MinioClient(url, accessKey, secretKey);
            String mainName = FileUtils.mainName(file.getOriginalFilename());
            //后缀名
            String extName = FileUtils.extName(file.getOriginalFilename());
            // 获取文件名称
            String fileName = null;
            if (StringUtils.isBlank(folderName)) {
                fileName = "other/" + mainName + "_" + DateUtils.dateTimeNow() + "." + extName;
            } else {
                fileName = folderName + "/" + mainName + "_" + DateUtils.dateTimeNow() + "." + extName;
            }
            if (!minioClient.bucketExists(bucketName)) {
                minioClient.makeBucket(bucketName);
                System.out.println("1. ---->" + minioClient.getBucketPolicy(bucketName));
                String policy = "{\n" +
                        "    \"Version\": \"2012-10-17\",\n" +
                        "    \"Statement\": [\n" +
                        "        {\n" +
                        "            \"Action\": [\n" +
                        "                \"s3:GetObject\"\n" +
                        "            ],\n" +
                        "            \"Effect\": \"Allow\",\n" +
                        "            \"Principal\": {\n" +
                        "                \"AWS\": [\n" +
                        "                    \"*\"\n" +
                        "                ]\n" +
                        "            },\n" +
                        "            \"Resource\": [\n" +
                        "                \"arn:aws:s3:::" + bucketName + "/*\"\n" +
                        "            ]\n" +
                        "        }\n" +
                        "    ]\n" +
                        "}";
                minioClient.setBucketPolicy(bucketName, policy);
                System.out.println("2. ---->" + minioClient.getBucketPolicy(bucketName));

            }
            // 放入minio
            minioClient.putObject(bucketName, fileName, is, file.getSize(), file.getContentType());

            // 获取访问全路径
            String pathUrl = minioClient.getObjectUrl(bucketName, fileName);

            // 替换访问路径前缀
            pathUrl = pathUrl.replace(url, "");
            return success(URLDecoder.decode(pathUrl, StandardCharsets.UTF_8.name()));

        } catch (Exception e) {
            log.info("minio上传异常: {}", e.getMessage(), e);
            return error("上传失败！");
        }

    }

    /**
     * 下载minio服务的文件
     *
     * @param response
     * @return
     */
    @ApiOperation("文件下载")
    @GetMapping("/download")
    public String download(HttpServletResponse response, @RequestParam("fileName") String fileName) {
        try {
            MinioClient minioClient = new MinioClient(url, accessKey, secretKey);
            InputStream fileInputStream = minioClient.getObject(bucketName, fileName);
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setContentType("application/force-download");
            response.setCharacterEncoding("UTF-8");
            IOUtils.copy(fileInputStream, response.getOutputStream());
            return "下载完成";
        } catch (Exception e) {
            log.info("异常: {}", e.getMessage(), e);
            return "下载失败";
        }
    }

    /**
     * 获取minio文件的url路径
     *
     * @return
     */
    @ApiOperation("获取文件url路径")
    @GetMapping("/url")
    public String getUrl(@RequestParam("fileName") String fileName) {
        try {
            MinioClient minioClient = new MinioClient(url, accessKey, secretKey);
            String url = minioClient.presignedGetObject(bucketName, fileName);
            return url;
        } catch (Exception e) {
            e.printStackTrace();
            return "获取失败";
        }
    }
}
